package com.example.onlinemonitoring.comCenter;

import java.text.ParseException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.${demo.simplename?cap_first}history;
import com.example.onlinemonitoring.model.${demo.simplename?cap_first}sensor;
import com.example.onlinemonitoring.serviceImpl.${demo.simplename?cap_first}sensorServiceImpl;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import lombok.Data;

import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * freemarker填充
 */
@Service("${demo.simplename}Com")
@Scope("prototype")
public class ${demo.simplename?cap_first}Com extends CommPortManager {
    @Autowired
    private ${demo.simplename?cap_first}sensorServiceImpl ${demo.simplename}serviceimpl;

    public void receiveDatas(String str) {
        str = str.toUpperCase();
        setText(str);
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);
        reSend[addrindex] = 0;
        if (currcmd == 1) {
            addrindex++;
        }
        String cmdstr = str.substring(2, 4);
        Integer cmdint = parseHex4(cmdstr);
        byte[] carr = HexUtil.hexString2Bytes(str);
        Date dt = new Date();
        ${demo.simplename?cap_first}sensor ${demo.simplename} = new ${demo.simplename?cap_first}sensor();
        ${demo.simplename}.setStationid(ad.getStationid());
        ${demo.simplename}.setDevicegroup(ad.getDevicegroup());
        ${demo.simplename}.setDeviceaddr(addrint);
        ${demo.simplename?cap_first}sensor record = ${demo.simplename}serviceimpl.getModel(${demo.simplename});
        ${demo.simplename}.setLastdatatime(dt);
        switch (cmdint) {
            case 1://freemarker填充                
                <#list demo.yaoxin as yaoxin>
                ${demo.simplename}.setLast${yaoxin.name?uncap_first}(parseHex4(str.substring(,)));// ${yaoxin.comment}
                </#list>
                <#list demo.yaoxin as yaoxin>
                //${demo.simplename}.setLast${yaoxin.name?uncap_first}(carr[3] >> 0 & 1);// ${yaoxin.comment}
                </#list>
                String alm = "";
                ${demo.simplename}.setLastalarmlevel(0);
                ${demo.simplename}.setLastalarmmessage("");
                if(${demo.simplename}.getLast() == 1){//freemarker填充
                    alm+=","; //freemarker填充
                    ${demo.simplename}.setLastalarmlevel(2);
                    ${demo.simplename}.setLastalarmmessage(alm);
                }
                if(alm.length() == 0){
                    GetNormalAlarm("中文名称"+record.getDeviceaddr(), record.getDeviceaddr(),0, record.getPointname(), "", false);//freemarker填充
                    setText("无报警");
                }else{
                    GetNormalAlarm("中文名称"+record.getDeviceaddr(), record.getDeviceaddr(),0, record.getPointname(), alm, true);//freemarker填充
                    setText(alm);
                }
                break;
            case 3: //freemarker填充
                int startindex = 0;//freemarker填充
                <#list demo.yaoce as yaoce>
                ${demo.simplename}.setLast${yaoce.name?uncap_first}(parseHex4(str.substring(startindex, startindex+=4)) * 1.0f);// ${yaoce.comment}
                </#list>
                <#list demo.yaoce as yaoce>
                //${demo.simplename}.setLast${yaoce.name?uncap_first}(IEEE754Utils.strbytesToSingleTurn(str.substring(startindex, startindex+=8)).floatValue() * 1.0f);// ${yaoce.comment}
                </#list>
                ${demo.simplename}.setLastcommunicationstatus(0);
                ${demo.simplename}.setLasthisdatatime(addHistory(${demo.simplename}));
                setText("设备返回数据： 站点号：1 监测点" + addrint);
                <#list demo.yaoce as yaoce>
                setText("${yaoce.comment}" + ${demo.simplename}.getLast${yaoce.name?uncap_first}());
                </#list>
                break;
            default:
                break;
        }
        ${demo.simplename}serviceimpl.Update(${demo.simplename}, false);
    }
    private Date addHistory(${demo.simplename?cap_first}sensor sensor) {
        sensor = ${demo.simplename}serviceimpl.getModel(sensor);
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp()*1000;
                } else {
                    timersp = ad.getHistimersp()*1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }
    private void add(${demo.simplename?cap_first}sensor sensor) {
        ${demo.simplename?cap_first}history his = new ${demo.simplename?cap_first}history();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDatatime(sensor.getLastdatatime());
        his.setPointname(sensor.getPointname());

        //需要添加自己定义的属性
        //  todo
        <#list demo.yaoce as yaoce>
        his.set${yaoce.name?cap_first}(sensor.getLast${yaoce.name}());
        </#list>
        <#list demo.yaoxin as yaoxin>
        his.set${yaoxin.name?cap_first}(sensor.getLast${yaoxin.name}());
        </#list>
        ${demo.simplename}serviceimpl.Add(his);
    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        String cmd[] = new String[3];
        cmd[0] = "%s0100000025";// 遥信  freemarker填充
        cmd[1] = "%s0300000008";// 遥测  freemarker填充
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            try {
                if (isrun) {
                    if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                        addrindex = Appdevice.getAddrmin();
                    cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                    Send(cstr);
                    sendCondition.await(timeoutsp,TimeUnit.MILLISECONDS);
                    currcmd++;
                    cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                    Send(cstr);
                    sendCondition.await(timeoutsp,TimeUnit.MILLISECONDS);
                    currcmd = 0;
                    if (reSend[addrindex] > 3) {
                        ${demo.simplename}serviceimpl.UpdateStatus(ad, addrindex, 1);
                        reSend[addrindex] = 0;
                        addrindex++;
                    }
                    reSend[addrindex]++;
                } else if (rescode != 0) {
                    setText(resmsg[rescode]);
                }
            } catch (Exception e) {
                // TODO: handle exception
            }finally{
                rlock.unlock();
            }
        }
    }
}